﻿using System;
using System.Threading.Tasks;
using FortuneUniverse.Fortune.Algorithms;

namespace FortuneUniverse.Fortune.Dyson
{
  public class PlanetAlgorithm4 : PlanetAlgorithm
  {
    public override void GenerateTerrain(double modX, double modY)
    {
      double num = 0.007;
      double num2 = 0.007;
      double num3 = 0.007;
      URandom1 urandom1 = new URandom1(this.planet.seed);
      int seed1 = urandom1.Next();
      int seed2 = urandom1.Next();
      SimplexNoise simplexNoise = new SimplexNoise(seed1);
      SimplexNoise simplexNoise2 = new SimplexNoise(seed2);
      int seed3 = urandom1.Next();
      Vector4[] circles = new Vector4[80];
      double[] heights = new double[80];
      for (int index = 0; index < 80; ++index)
      {
        VectorLF3 vectorLf3 = RandomTable.SphericNormal(ref seed3, 1.0);
        Vector4 vector4 = new Vector4((float) vectorLf3.x, (float) vectorLf3.y, (float) vectorLf3.z);
        vector4.Normalize();
        vector4 *= this.planet.radius;
        vector4.w = (float) (vectorLf3.magnitude * 8.0 + 8.0);
        vector4.w *= vector4.w;
        circles[index] = vector4;
        heights[index] = urandom1.NextDouble() * 0.4 + 0.200000002980232;
      }
      PlanetRawData data = this.planet.data;
      Parallel.For(0, data.dataLength, (Action<int>) (j =>
      {
        double num1 = (double) data.vertices[j].x * (double) this.planet.radius;
        double num4 = (double) data.vertices[j].y * (double) this.planet.radius;
        double num5 = (double) data.vertices[j].z * (double) this.planet.radius;
        double num6 = simplexNoise.Noise3DFBM(num1 * num, num4 * num2, num5 * num3, 4, 0.45, 1.8);
        double num7 = simplexNoise2.Noise3DFBM(num1 * num * 5.0, num4 * num2 * 5.0, num5 * num3 * 5.0, 4);
        double num8 = num6 * 1.5;
        double num9 = num7 * 0.2;
        double num10 = num8 * 0.08 + num9 * 2.0;
        double num11 = 0.0;
        for (int index = 0; index < 80; ++index)
        {
          double num12 = (double) circles[index].x - num1;
          double num13 = (double) circles[index].y - num4;
          double num14 = (double) circles[index].z - num5;
          double num15 = num12 * num12 + num13 * num13 + num14 * num14;
          if (num15 <= (double) circles[index].w)
          {
            double num16 = num15 / (double) circles[index].w + num9 * 1.2;
            if (num16 < 0.0)
              num16 = 0.0;
            double num17 = num16 * num16;
            double num18 = -15.0 * (num17 * num16) + 131.0 / 6.0 * num17 - 113.0 / 15.0 * num16 + 0.7 + num9;
            if (num18 < 0.0)
              num18 = 0.0;
            double num19 = num18 * num18 * heights[index];
            num11 = num11 <= num19 ? num19 : num11;
          }
        }
        double num20 = num11 + num10 + 0.2;
        data.heightData[j] = (ushort) (((double) this.planet.radius + num20 + 0.1) * 100.0);
      }));
    }
  }
}
